from tools.hd_logger import HdLogger
from db_tools.db_handler import DbHandler
import threading


def synchronized(func):
    """
    线程安全的装饰器,加一个线程锁
    :param func:
    :return:
    """
    func.__lock__ = threading.Lock()

    def lock_func(*args, **kwargs):
        with func.__lock__:
            return func(*args, **kwargs)

    return lock_func


class ConfigParams(object):
    __cpInstance__ = None
    __initFlag__ = False

    @synchronized
    def __new__(cls, *args, **kwargs):
        if cls.__cpInstance__ is None:
            cls.__cpInstance__ = object.__new__(cls)
        return cls.__cpInstance__

    def __init__(self):
        if not self.__initFlag__:
            print("ConfigParams.__init__() 进行初始化")
            self.db = DbHandler()
            self.logger = HdLogger()
            self.reload_config_params()
            self.__initFlag__ = True

    def reset_one_lot_board_count(self):
        """
        重置放板的数量0,位置偏移为0,计数为0.
        :return:
        """
        newData = {
            "nowLotCount":0,
            "oneLotOffset":0,
        }
        self.db.save_config_params(newData)
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        if res != "ok":
            errorInfo = "in ConfigParams.reload_config_params() error: {}".format(configParams)
            print(errorInfo)
            self.logger.debug(errorInfo)
        else:
            self.nowLotCount = configParams.get("nowLotCount",0) # 当前的计数, 如果这个计数满了25个. 就重置为0,然后将那个位置偏移改成0或者是从0变成30
            self.oneLotOffset = configParams.get("oneLotOffset",30) # 一批计数偏移多少个mm,x轴正向30个mm

    def add_one_board_count(self):
        offsetX = self.offsetX
        if self.nowLotCount == 0:
            offsetX = 0
        else:
            if self.nowLotCount % self.oneLotCount == 0:
                if self.oneLotOffset != 0:
                    offsetX = 0
                else:
                    offsetX = self.oneLotOffset
        newData = {
            "nowLotCount": self.nowLotCount + 1,
            "offsetX":offsetX
        }
        self.db.save_config_params(newData)
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        if res != "ok":
            errorInfo = "in ConfigParams.reload_config_params() error: {}".format(configParams)
            print(errorInfo)
            self.logger.debug(errorInfo)
        else:
            self.nowLotCount = configParams.get("nowLotCount", 0)  # 当前的计数, 如果这个计数满了25个. 就重置为0,然后将那个位置偏移改成0或者是从0变成30
            self.oneLotOffset = configParams.get("oneLotOffset", 30)  # 一批计数偏移多少个mm,x轴正向30个mm
            self.offsetX = configParams.get("offsetX",0) # X轴的偏移,要不就是0,要不就是30

    def web_request_save_config_parms(self,newData):
        res, info = self.db.save_config_params(newData)
        if res == "ok":
            self.reload_config_params()
            return "ok"
        else:
            return info

    def web_request_get_config_params(self):
        """
        前端界面请求获取configParams参数
        :return:
        """
        res,data = self.db.get_data_one(self.db.configParamsTable,query={"key":"1"})
        return [data] if res == "ok" else []

    def reload_config_params(self):
        """
        重新加载设备参数,包括相机和算法,将设备的参数加载刷新一次.
        :return:
        """
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        if res != "ok":
            errorInfo = "in ConfigParams.reload_config_params() error: {}".format(configParams)
            print(errorInfo)
            self.logger.debug(errorInfo)
        else:
            self.centerModuleX = configParams.get("centerModuleX",123)
            self.centerModuleY = configParams.get("centerModuleY",123)
            self.centerImageX = configParams.get("centerImageX",1480)
            self.centerImageY = configParams.get("centerImageY",1523)
            self.catchPosOffset4pin = configParams.get("catchPosOffset",260)
            self.catchPosOffset6pin = configParams.get("catchPosOffset6pin",200)
            self.angleOffset  = configParams.get("angleOffset",123)
            self.mm2pix = configParams.get("MMpix",123)
            self.maxIndex = configParams.get("maxIndex",1000)
            self.errorAngleThres = configParams.get("angleThres",20)
            self.saveMaxImage = configParams.get("saveMaxImage", 200)
            self.smallBoardRange = configParams.get("smallBoardRange",450) # 小于这个尺寸的板子抓中心.
            # self.smallBoardRange = self.catchPosOffset4pin * 2
            self.thresUsed = configParams.get("thresUsed",180) # 识别亮度阈值,默认是180
            self.OCR_LastBoardIndex = configParams.get("ocr_LastBoardIndex",1) # OCR使用的识别的板子的编号.
            self.OCR_LastDate = configParams.get("ocr_LastDate","0302") # 后面使用的日期
            self.nowLotCount = configParams.get("nowLotCount",0) # 当前的计数, 如果这个计数满了25个. 就重置为0,然后将那个位置偏移改成0或者是从0变成30
            self.oneLotCount = configParams.get("oneLotCount",25) # 一批计数
            self.oneLotOffset = configParams.get("oneLotOffset",30) # 一批计数偏移多少个mm,x轴正向30个mm
            self.offsetX = configParams.get("offsetX",0) # offsetX的偏移值,要不是0,要不就是oneLotOffset设置的30

            self.intervalThres = configParams.get("intervalThres", 30)  # 一块板子的节拍时间间隔,目前是15秒左右.如果时间小于15秒,并且IndexError > 3,就按照+1去推测.
            self.indexErrorMax = configParams.get("indexErrorMax", 3)  # IndexError如果超过了这个值,就认为是可能错误的类型.

            print("参数加载: 图像中心对应模组坐标: x = {}, y = {},抓取位置偏移 = ({},{}),角度调整补偿 = {},像素比 = {},保存最大图像数 = {},角度阈值 = {},识别亮度阈值 = {}".format(
                self.centerModuleX,self.centerModuleY,self.catchPosOffset4pin,self.catchPosOffset6pin,
                self.angleOffset,self.mm2pix,self.maxIndex,self.errorAngleThres,self.thresUsed))


if __name__ == '__main__':
    hd = HdLogger()
    hd.debug("gjsadgfkas")
